package cheme.ProcessEditor.Tools;

import org.eclipse.draw2d.ActionEvent;
import org.eclipse.draw2d.ActionListener;
import org.eclipse.draw2d.Button;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.swt.graphics.Image;

/*
 * A button that can be placed within a figure whose behavior is like that
 * of a tool--that is, it initiates requests, sends them to a target editpart
 * which may then transform the request into an actionable command. Which the 
 * ButtonTool then passes on to the command stack execution process. 
 */
public class ButtonTool extends Button
{
	Request request;
	EditPart targetEditPart;
	
	/**
	 * 
	 */
	public ButtonTool()
	{
		super();
		internalInit();
	}
	/**
	 * @param image
	 */
	public ButtonTool(Image image)
	{
		super(image);
		internalInit();
	}
	/**
	 * @param text
	 * @param image
	 */
	public ButtonTool(String text, Image image)
	{
		super(text, image);
		internalInit();
	}
	
	/**
	 * @param text
	 */
	public ButtonTool(String text)
	{
		super(text);
		internalInit();
	}
	
	@Override
	public Dimension getMinimumSize(int wHint, int hHint)
	{
		Dimension superPref = super.getMinimumSize(wHint, hHint);
		return superPref.union(new Dimension(20,20));
	}
	
	public Request getRequest()
	{
		return request;
	}
	
	public void setRequest(Request request)
	{
		this.request = request;
	}
	
	public EditPart getTargetEditPart()
	{
		return targetEditPart;
	}
	
	public void setTargetEditPart(EditPart targetEditPart)
	{
		this.targetEditPart = targetEditPart;
	}
	
	private void internalInit()
	{
		addActionListener(new RequestEmitter());
	}
		
	private class RequestEmitter implements ActionListener
	{
		public void actionPerformed(ActionEvent event)
		{
			if(null != targetEditPart)
			{			
				Command cmd = targetEditPart.getCommand(request);
				executeCommand(cmd);
			}
		}
		
		/**
		 * Executes the given command on the command stack.
		 * @param command the command to execute
		 */
		protected void executeCommand(Command command)
		{
			try
			{
				getEditDomain().getCommandStack().execute(command);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
		public EditDomain getEditDomain()
		{
			if(null != targetEditPart)
			{
				return targetEditPart.getViewer().getEditDomain();
			}
			
			return null;
		}
	}
}
